home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / examples / selection / pickSolar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  8.7 KB  |  350 lines

  1. /*
  2.  * Copyright 1993, 1996, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /*  pickSolar.c
  19.  *    This program demonstrates how to pick objects in a scene.
  20.  *
  21.  *    Left Mouse Button, down     - pick object(s)
  22.  *    <r> key                - toggle rotation on/off
  23.  *    Escape key            - exit the program
  24.  */
  25. #include <GL/gl.h>
  26. #include <GL/glu.h>
  27. #include <GL/glut.h>
  28.  
  29. #include <stdio.h>
  30. #include <math.h>
  31.  
  32. /* Function Prototypes */
  33.  
  34. GLvoid initgfx( GLvoid );
  35. GLvoid drawScene( GLvoid );
  36. GLvoid reshape( GLsizei, GLsizei );
  37. GLvoid keyboard( GLubyte, GLint, GLint );
  38. GLvoid animate( GLvoid );
  39. GLvoid visibility( int );
  40. GLvoid mouse( GLint, GLint, GLint, GLint );
  41.  
  42. void doPicking( int x, int y );
  43. void printHits( GLint, GLint, GLint, GLuint [] );
  44. void printHelp( char * );
  45.  
  46. /* Global Definitions */
  47.  
  48. #define KEY_ESC    27    /* ascii value for the escape key */
  49.  
  50. #define BUFSIZE 512    /* hit buffer size */
  51.  
  52. #define UNNAMED_OBJECT    (-1)    /* marks empty name stack */
  53.  
  54. /* Global Variables */
  55.  
  56. static GLboolean picking = GL_FALSE;
  57. static GLboolean rotateFlag = GL_TRUE;
  58.  
  59. static GLdouble depthNormalizeFactor, znear = 6.0, zfar = 14.0;
  60.  
  61. /* matrices for gluUnProject */
  62. static GLdouble modelview[16], projection[16];
  63. static GLint     viewport[4];
  64.  
  65. static enum shapes { SUN, EARTH, MOON };
  66. static char *shapeNames[] =  { "Sun", "Earth", "Moon" };
  67.  
  68. static GLboolean pickedFlag[ MOON + 1 ] = { GL_FALSE };
  69.  
  70. static GLfloat year = 0;
  71.  
  72. void
  73. main( int argc, char **argv )
  74. {
  75.     GLsizei width, height;
  76.  
  77.     glutInit( &argc, argv );
  78.  
  79.     width = glutGet( GLUT_SCREEN_WIDTH ); 
  80.     height = glutGet( GLUT_SCREEN_HEIGHT );
  81.     glutInitWindowPosition( width / 4, height / 4 );
  82.     glutInitWindowSize( (width / 2) - 4, height / 2 );
  83.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
  84.     glutCreateWindow( argv[0] );
  85.  
  86.     initgfx();
  87.  
  88.     glutMouseFunc( mouse );
  89.     glutKeyboardFunc( keyboard );
  90.     glutReshapeFunc( reshape );
  91.     glutIdleFunc( animate ); 
  92.     glutVisibilityFunc( visibility ); 
  93.     glutDisplayFunc( drawScene ); 
  94.  
  95.     printHelp( argv[0] );
  96.  
  97.     glutMainLoop();
  98. }
  99.  
  100. GLvoid
  101. printHelp( char *progname )
  102. {
  103.     fprintf(stdout, "%s - program demonstrates picking\n\n"
  104.         "Left Mouse Button, down     - pick object(s)\n"
  105.         "<r> key            - toggle rotation on/off \n"
  106.         "Escape key            - exit the program \n\n",
  107.         progname );
  108. }
  109.  
  110. void
  111. initgfx()
  112. {
  113.     GLfloat mat_specular[] = { 0.8, 0.8, 0.8, 1.0 };
  114.     GLfloat mat_shininess[] = { 10.0 };
  115.     GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
  116.  
  117.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  118.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  119.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
  120.     glEnable( GL_LIGHTING );
  121.     glEnable( GL_LIGHT0 );
  122.  
  123.     glClearColor( 0, 0, 0, 1 );
  124.     glEnable( GL_DEPTH_TEST );
  125.  
  126.     /* depth values in hit record are in the range 0 to 2**32 - 1 */
  127.     depthNormalizeFactor = pow(2, 32) - 1;
  128. }
  129.  
  130. GLvoid 
  131. keyboard( GLubyte key, GLint x, GLint y )
  132. {
  133.     switch (key) {
  134.     case 'r':     /* toggle rotation on/off */
  135.         rotateFlag = !rotateFlag;    
  136.         if ( rotateFlag ) 
  137.             glutIdleFunc( animate ); 
  138.         else 
  139.             glutIdleFunc( NULL ); 
  140.         glutPostRedisplay();
  141.         break;
  142.  
  143.     case KEY_ESC:    /* Exit whenever the Escape key is pressed */
  144.         exit(0);
  145.     }
  146. }
  147.  
  148. GLvoid 
  149. mouse( GLint button, GLint state, GLint x, GLint y )
  150. {
  151.     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  152.         doPicking( x, y );
  153.     }
  154. }
  155.  
  156. GLvoid  
  157. doPicking( int mouseX, int mouseY )
  158. {
  159.     GLuint selectBuf[BUFSIZE];
  160.     GLint hits;
  161.     GLdouble aspect;
  162.  
  163.     aspect = (GLdouble) viewport[2] / (GLdouble) viewport[3];
  164.  
  165.     mouseY = viewport[3] - mouseY;
  166.  
  167.     picking = GL_TRUE;
  168.  
  169.     glSelectBuffer (BUFSIZE, selectBuf);
  170.     (GLvoid) glRenderMode( GL_SELECT );
  171.     glInitNames();
  172.     glPushName( UNNAMED_OBJECT );
  173.  
  174.     glMatrixMode( GL_PROJECTION );
  175.     glPushMatrix();
  176.         glLoadIdentity();
  177.         gluPickMatrix( (GLdouble) mouseX, (GLdouble) mouseY, 
  178.             5, 5,  /* x, y pixel tolerance for pick */
  179.             viewport );
  180.         gluPerspective( 45.0, aspect, 6.0, 14.0 );
  181.         glMatrixMode( GL_MODELVIEW );
  182.  
  183.         drawScene();
  184.  
  185.         hits = glRenderMode( GL_RENDER );
  186.         printHits( hits, mouseX, mouseY, selectBuf );
  187.  
  188.         picking = GL_FALSE;
  189.  
  190.         glMatrixMode( GL_PROJECTION );
  191.     glPopMatrix();
  192.     glMatrixMode( GL_MODELVIEW );
  193.     glutPostRedisplay();    /* make sure scene is redrawn */
  194. }
  195.  
  196. GLvoid
  197. reshape( GLsizei width, GLsizei height )
  198. {
  199.     GLdouble    aspect;
  200.  
  201.     glViewport( 0, 0, width, height );
  202.  
  203.     aspect = (GLdouble) width / (GLdouble) height;
  204.  
  205.     glMatrixMode( GL_PROJECTION );
  206.     glLoadIdentity();
  207.     gluPerspective( 45.0, aspect, znear, zfar);
  208.     glMatrixMode( GL_MODELVIEW );
  209.     glLoadIdentity();
  210.  
  211.     glGetIntegerv( GL_VIEWPORT, viewport );
  212.     glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
  213.     glGetDoublev( GL_PROJECTION_MATRIX, projection );
  214. }
  215.  
  216. GLvoid
  217. animate( GLvoid )
  218. {
  219.     /* update the current year */
  220.     year = fmodf((year + 0.2), 360);
  221.  
  222.         /* Tell GLUT to redraw the scene */
  223.         glutPostRedisplay();
  224. }
  225.  
  226. GLvoid
  227. visibility( int state )
  228. {
  229.         if (state == GLUT_VISIBLE && rotateFlag) {
  230.                 glutIdleFunc( animate );
  231.         } else {
  232.                 glutIdleFunc( NULL );
  233.         }
  234. }
  235.  
  236. GLvoid
  237. drawScene( GLvoid )
  238. {
  239.     static GLfloat sun_diffuse[] = { 1.0, 1.0, 0.0, 1.0 };
  240.     static GLfloat sun_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  241.     static GLfloat no_specular[] = { 0.0, 0.0, 0.0, 1.0 };
  242.     static GLfloat earth_diffuse[] = { 0.0, 0.3, 1.0, 1.0 };
  243.     static GLfloat moon_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  244.     static GLfloat position[] = { 0.0, 0.0, 1.0, 0.0 };
  245.  
  246.     /* simulate local light centered at sun by rotating an
  247.      * infinite light */
  248.     static GLfloat sun_position[] = { -1.0, 0.0, 0.0, 0.0 };
  249.  
  250.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  251.  
  252.     glPushMatrix();
  253.  
  254.         /* sun surface lit by light attached to eye, 
  255.          * thus before viewing */
  256.         glLightfv(GL_LIGHT0, GL_POSITION, position);
  257.  
  258.         /* accomplish a viewing transformation by moving
  259.          * the world relative to the eye
  260.          */
  261.         glTranslatef(0.0, 0.0, -10.0);
  262.         glRotatef( 10.0, 1.0, 0.0, 0.0 );
  263.  
  264.         glPushMatrix();
  265.             glRotatef (90.0, 1.0, 0.0, 0.0);
  266.             glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_diffuse);
  267.             glMaterialfv(GL_FRONT, GL_SPECULAR, sun_specular);
  268.             glLoadName(SUN);
  269.             if ( pickedFlag[SUN] && !picking )
  270.                 glutWireSphere(0.7, 15, 15);
  271.             else    
  272.                 glutSolidSphere(0.7, 15, 15);
  273.         glPopMatrix();
  274.  
  275.         glPushMatrix();
  276.             glRotatef (year, 0.0, 1.0, 0.0);
  277.             glTranslatef (2.5, 0.0, 0.0);
  278.             glPushMatrix();
  279.                 /* infinite light looks like local light at 
  280.                  * sun because rotating in sync with planet */
  281.                 glLightfv(GL_LIGHT0, GL_POSITION, sun_position);
  282.                 glRotatef (90.0, 1.0, 0.0, 0.0);
  283.                 glMaterialfv(GL_FRONT, GL_SPECULAR, no_specular);
  284.                 glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_diffuse);
  285.                 glLoadName(EARTH);
  286.                 if ( pickedFlag[EARTH] && !picking )
  287.                     glutWireSphere(0.5, 15, 15);
  288.                 else    
  289.                     glutSolidSphere(0.5, 15, 15);
  290.             glPopMatrix();
  291.  
  292.             glPushMatrix();
  293.                 glRotatef ( fmodf( (year * 5.0), 360.0 ),
  294.                     0.0, 1.0, 0.0);
  295.                 glTranslatef (1.0, 0.0, 0.0);
  296.                 glRotatef (90.0, 1.0, 0.0, 0.0);
  297.                 glMaterialfv(GL_FRONT, GL_DIFFUSE, moon_diffuse);
  298.                 glPushName(MOON);
  299.                 if ( pickedFlag[MOON] && !picking )
  300.                     glutWireSphere(0.2, 15, 15);
  301.                 else    
  302.                     glutSolidSphere(0.2, 15, 15);
  303.             glPopMatrix();
  304.         glPopMatrix();
  305.  
  306.     glPopMatrix();
  307.  
  308.     ( picking ? glFlush() : glutSwapBuffers() );
  309. }
  310.  
  311. GLvoid 
  312. printHits (GLint hits, GLint x, GLint y, GLuint buffer[] )
  313. {
  314.     unsigned int i, j, nameCount;
  315.     GLuint *bufp;
  316.     GLdouble min_depth, max_depth, objx, objy, objz;
  317.     
  318.     printf ("hits = %d\n", hits);
  319.     bufp = (GLuint *) buffer;
  320.     for (i = 0; i < hits; i++) 
  321.     {    /*  for each hit  */
  322.         nameCount = *bufp; bufp++;
  323.         printf( " number of names for this hit = %d\n", 
  324.             nameCount ); 
  325.  
  326.         min_depth = ((GLdouble)(*bufp)/depthNormalizeFactor); bufp++;
  327.         gluUnProject( x, y, min_depth, modelview, projection, 
  328.                 viewport, &objx, &objy, &objz);
  329.         printf( " z1 = %f", objz );
  330.  
  331.         max_depth = ((GLdouble)(*bufp)/depthNormalizeFactor); bufp++;
  332.         gluUnProject( 0.0, 0.0, max_depth, modelview, projection, 
  333.                 viewport, &objx, &objy, &objz);
  334.         printf( " z2 = %f\n", objz );
  335.  
  336.         printf( " names are: " );
  337.         for ( j = 0; j < nameCount; j++, bufp++ ) 
  338.         {    /*  for each name */
  339.             if ((GLint) *bufp == UNNAMED_OBJECT ) {
  340.                 fprintf( stdout, "UNNAMED_OBJECT\n" );
  341.             } else {
  342.                 if (j == (nameCount - 1))
  343.                     pickedFlag[*bufp] = !pickedFlag[*bufp];
  344.                 fprintf( stdout, "\t%s", shapeNames[*bufp] );
  345.             }
  346.         }
  347.         printf( "\n\n" );
  348.     }
  349. }
  350.